package com.koron.standard.jobStock.maintain.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.koron.standard.bean.query.PageQuery;
import com.koron.standard.jobStock.maintain.bean.dto.MaintainDTO;
import com.koron.standard.jobStock.maintain.bean.dto.MaintainItemDTO;
import com.koron.standard.jobStock.maintain.bean.po.Maintain;
import com.koron.standard.jobStock.maintain.bean.query.MaintainQuery;
import com.koron.standard.jobStock.maintain.bean.vo.MaintainVO;
import com.koron.standard.jobStock.maintain.mapper.MaintainMapper;
import com.koron.standard.utils.CommonUtils;
import com.koron.standard.utils.StandardCodeTools;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 日常维护标准信息(Maintain)表服务实现类
 *
 * @author jzp
 * @since 2021-09-06
 */
@Service
public class MaintainService extends ServiceImpl<MaintainMapper, Maintain> {

    @Autowired
    private MaintainItemService maintainItemService;

    public Page<MaintainVO> page(PageQuery<MaintainVO> pageQuery, MaintainQuery query) {
        // 设置默认只查有权限的水司数据
        query.setAppids(CommonUtils.getDefaultAppids(query.getAppids()));
        query.setPublicStatus(CommonUtils.getDefaultPublicStatus(query.getPublicStatus()));

        QueryWrapper<MaintainVO> wrapper = new QueryWrapper<>();
        wrapper.like(StrUtil.isNotEmpty(query.getCode()), "c_maintain.code", query.getCode());
        wrapper.like(StrUtil.isNotEmpty(query.getName()), "c_maintain.name", query.getName());
        wrapper.eq(StrUtil.isNotEmpty(query.getTypeId()), "c_maintain.type_id", query.getTypeId());
        wrapper.like(StrUtil.isNotEmpty(query.getTypeName()), "c_type.name", query.getTypeName());

        if (query.getPublicStatus() != null && query.getPublicStatus() > 0) {
            // 如果是共有的
            wrapper.and(w -> w.eq("c_maintain.public_status", query.getPublicStatus())
                    .or(CollUtil.isNotEmpty(query.getAppids()))
                    .in(CollUtil.isNotEmpty(query.getAppids()), "c_maintain.appid", query.getAppids()));
        } else {
            wrapper.in(CollUtil.isNotEmpty(query.getAppids()), "c_maintain.appid", query.getAppids());
        }

        wrapper.eq(query.getStatus()!=null, "c_maintain.status", query.getStatus());
        wrapper.eq(StrUtil.isNotEmpty(query.getDeptId()), "c_maintain.dept_id", query.getDeptId());
        wrapper.like(StrUtil.isNotEmpty(query.getDeptName()), "c_maintain.dept_name", query.getDeptName());
        if (CollUtil.isNotEmpty(query.getDates())) {
            wrapper.between("c_maintain.create_time", query.getDates().get(0), query.getDates().get(1));
        }
        wrapper.eq("c_maintain.delete_flag", 0);

        Page<MaintainVO> page = pageQuery.convertPage();
        List<OrderItem> orders = pageQuery.getOrders();
        for (OrderItem order : orders) {
            if (order.getColumn().equals("type_name")) {
                order.setColumn("c_type.name");
            } else if (order.getColumn().equals("app_name")) {
                order.setColumn("s_app.name");
            } else {
                order.setColumn("c_maintain." + order.getColumn());
            }
        }
        getBaseMapper().selectPageVo(page, wrapper);
        return page;
    }

    public MaintainDTO getDtoById(String id) {
        MaintainVO maintainVO = getBaseMapper().getVoById(id);
        MaintainDTO maintainDTO = new MaintainDTO();
        BeanUtils.copyProperties(maintainVO, maintainDTO);
        List<MaintainItemDTO> maintainItemDTOs = maintainItemService.getTreeByMaintainId(id);
        maintainDTO.setItemDTOs(maintainItemDTOs);
        return maintainDTO;
    }

    /**
     * 筛选除有标准的分类id
     */
    public List<String> filterTypeIds(List<String> typeIds) {
        LambdaQueryWrapper<Maintain> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CollUtil.isNotEmpty(typeIds), Maintain::getTypeId, typeIds);
        List<Maintain> list = list(wrapper);
        return list.stream().map(Maintain::getTypeId).distinct().collect(Collectors.toList());
    }

    public void saveDto(MaintainDTO maintainDTO) {
        // 设置编码
        maintainDTO.setCode(StandardCodeTools.getMaintainJobCode());

        // 默认草稿
        maintainDTO.setStatus(0);

        // 保存
        updateDtoById(maintainDTO);

    }

    @Transactional(rollbackFor = RuntimeException.class)
    public void updateDtoById(MaintainDTO maintainDTO) {
        // 1. 删除所有子项-日常维护标准下作业项目树
        maintainItemService.removeByMaintainId(maintainDTO.getId());

        // 2. 保存或更新基本信息
        saveOrUpdate(maintainDTO);

        // 3. 保存节点信息
        List<MaintainItemDTO> maintainItemDTOs = Optional.ofNullable(maintainDTO.getItemDTOs()).orElse(new ArrayList<>());
        for (MaintainItemDTO maintainItemDTO : maintainItemDTOs) {
            maintainItemDTO.setMaintainId(maintainDTO.getId());
            maintainItemService.saveRootDto(maintainItemDTO); // 会递归保存所有子节点信息
        }

    }

    public void updateToPublic(List<String> ids) {
        List<Maintain> maintains = new ArrayList<>();
        for (String id : ids) {
            Maintain maintain = new Maintain();
            maintain.setId(id);
            maintain.setPublicStatus(1);
            maintains.add(maintain);
        }
        updateBatchById(maintains);
    }

    public void updateStatus(String id, Integer status) {
        LambdaUpdateWrapper<Maintain> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Maintain::getId, id);
        wrapper.set(Maintain::getStatus, status);
        update(wrapper);
    }
}
